<script lang="ts" setup>
import { avatarUpload } from '@/api/system/users/index.ts'
const imgFile = ref<{
    dataurl: string | ArrayBuffer | null | undefined,
    name: string
}>({
    dataurl: undefined,
    name: ''
})

const props = defineProps({
    src: {
        type: String,
        default: ''
    }
})

const fileInput = ref()
const cropperselection = ref();
const dialogVisible = ref(false)
const showMask = ref(false)

function loadingImg(e: any) {
    const file = e.target.files[0]
    imgFile.value.name = file.name
    if (!file) {
        console.log('No file selected.');
        return;
    }
    const reader = new FileReader()
    reader.readAsDataURL(file)
    reader.onload = (e) => {
        imgFile.value.dataurl = e.target?.result
        dialogVisible.value = true
    }
}

const circleCanvas = ref(); // 圆形图片
async function upload() {
    if (!imgFile.value) return
    const res = await cropperselection.value.$toCanvas();
    // 圆形图片
    // 创建一个新的canvas来处理圆形裁剪
    const circularCanvas = circleCanvas.value;
    const context = circularCanvas.getContext('2d');
    // 设置canvas的宽高与裁剪区域相同
    const size = Math.min(res.width, res.height); // 确保是正方形
    circularCanvas.width = size;
    circularCanvas.height = size;
    // 绘制圆形裁剪区域
    context.beginPath();
    context.arc(size / 2, size / 2, size / 2, 0, Math.PI * 2); // 在中心绘制圆形
    context.closePath();
    context.clip(); // 剪切区域
    // 在圆形剪切区域内绘制图片
    context.drawImage(res, 0, 0, size, size);
    // 导出圆形图片数据
    const dataImage = circularCanvas.toDataURL('image/png');
    const file = dataURLtoFile(dataImage, imgFile.value.name);

    try {
        const formData = new FormData()
        formData.append('file', file);
        const { data } = await avatarUpload(formData)
        if (data.code === 200) {
            ElMessage.success('上传成功')
            dialogVisible.value = false
            window.location.reload()
        } else {
            ElMessage.error('上传失败')
        }
    } catch (err) {
        ElMessage.error('上传请求异常')
    }
    finally {
        cropperselection.value.$change(0, 0, 100, 100);
        cropperselection.value.$center();
    }
}

function dialogClose() {
    fileInput.value.value = ''
    cropperselection.value.$change(0, 0, 100, 100);
    cropperselection.value.$center();
}

// 将data:image转成新的file
function dataURLtoFile(dataurl: string, filename: string) {
    var arr = dataurl.split(','),
        bstr = atob(arr[1]),
        n = bstr.length,
        u8arr = new Uint8Array(n);
    const matchResult = arr[0].match(/:(.*?);/);
    var mime = matchResult ? matchResult[1] : 'default/mime';
    while (n--) {
        u8arr[n] = bstr.charCodeAt(n);
    }
    const blob = new Blob([u8arr], { type: mime });
    const file = new File([blob], filename, { type: mime });
    return file;
}
</script>

<template>
    <div>
        <div class="avatar" @mouseover="showMask = true" @mouseout="showMask = false" @click="fileInput.click()">
            <Avatar :url="props.src" :size="100" />
            <transition name="fade">
                <div v-if="showMask" class="mask">
                    <div text-center font-mashanzheng>更换头像</div>
                </div>
            </transition>
        </div>
        <input type="file" accept="image/*" @change="loadingImg" ref="fileInput" hidden />
        <ElDialog v-model="dialogVisible" title="头像上传" @close="dialogClose" width="500px">
            <div style="display: flex;">
                <div style="width: 400px;height: 300px;">
                    <cropper-canvas background style="width: 100%;height: 100%;">
                        <cropper-image :src="imgFile.dataurl" alt="头像" rotatable scalable skewable
                            translatable></cropper-image>
                        <cropper-shade hidden style="border-radius: 50%;"></cropper-shade>
                        <cropper-handle action="move" plain></cropper-handle>
                        <cropper-selection initial-coverage="0.5" movable resizable id="cropperSelection"
                            :aspectRatio="1" ref="cropperselection" outlined>
                            <cropper-grid role="grid" covered></cropper-grid>
                            <cropper-crosshair centered></cropper-crosshair>
                            <cropper-handle action="move" theme-color="rgba(255, 255, 255, 0.35)"></cropper-handle>
                            <cropper-handle action="n-resize"></cropper-handle>
                            <cropper-handle action="e-resize"></cropper-handle>
                            <cropper-handle action="s-resize"></cropper-handle>
                            <cropper-handle action="w-resize"></cropper-handle>
                            <cropper-handle action="ne-resize"></cropper-handle>
                            <cropper-handle action="nw-resize"></cropper-handle>
                            <cropper-handle action="se-resize"></cropper-handle>
                            <cropper-handle action="sw-resize"></cropper-handle>
                        </cropper-selection>
                    </cropper-canvas>
                </div>

                <div
                    style="width: 100px;margin-left: 20px;display: flex;flex-direction: column;justify-content: center;align-items: center;padding: 0;">
                    <p>预览</p>
                    <div>
                        <cropper-viewer selection="#cropperSelection"
                            style="width: 100px;height: 100px;"></cropper-viewer>
                    </div>
                    <p>100X100</p>
                    <div>
                        <cropper-viewer selection="#cropperSelection"
                            style="width: 50px;height: 50px;"></cropper-viewer>
                    </div>
                    <p>50X50</p>
                </div>
                <canvas ref="circleCanvas" hidden></canvas>
            </div>
            <br />
            <div style="text-align: end;">
                <ElButton type="primary" @click="upload">上传</ElButton>
            </div>
        </ElDialog>
    </div>
</template>

<style scoped lang="scss">
cropper-viewer {
    border-radius: 50%;
}

.avatar {
    position: relative;
    width: 100px;
    height: 100px;
    background-color: aqua;
    border-radius: 50%;
}

.mask {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background-color: rgba(0, 0, 0, 0.5);
    color: white;
    font-weight: bold;
    display: flex;
    justify-content: center;
    align-items: center;
    border-radius: 50%;
    cursor: pointer;
    user-select: none;
}

.text {
    text-align: center;
    padding: 10px;
}


.fade-enter-active,
.fade-leave-active {
    transition: opacity 0.3s;
}

.fade-enter-from,
.fade-leave-to {
    opacity: 0;
}
</style>